home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Qu.......ke Neue Level
/
KroGer Software GmbH - Qu_ke.iso
/
UTILITY
/
PRG8.ZIP
/
F_BITMAP.C
next >
Wrap
C/C++ Source or Header
|
1996-03-02
|
10KB
|
358 lines
/*
* Copyright (C) 1996 by Raphael Quinet. All rights reserved.
*
* Permission to use, copy, modify, and distribute this software and
* its documentation for any purpose and without fee is hereby
* granted, provided that the above copyright notice appear in all
* copies and that both that copyright notice and this permission
* notice appear in supporting documentation. If more than a few
* lines of this code are used in a program which displays a copyright
* notice or credit notice, the following acknowledgment must also be
* displayed on the same screen: "This product includes software
* developed by Raphael Quinet for use in the Quake Editing Utilities
* project." THIS SOFTWARE IS PROVIDED "AS IS" WITHOUT EXPRESS OR
* IMPLIED WARRANTY.
*
* More information about the QEU project can be found on the WWW:
* "http://www.montefiore.ulg.ac.be/~quinet/games/editing.html" or by
* mail: Raphael Quinet, 9 rue des Martyrs, B-4550 Nandrin, Belgium.
*/
/*
* F_BITMAP.C - Filters for bitmap file formats.
*/
#include "qeu.h"
#include "q_misc.h"
#include "q_files.h"
#include "f_bitmap.h"
/* ------------------------------------------------------------------------- */
/* --- Routines for 256 colors palettes ------------------------------------ */
/*
* Read an RGB palette (256 * 3 bytes) from a file.
*/
struct RGB *ReadPalette256(FILE *file, UInt32 offset)
{
struct RGB *palptr;
if (file == NULL)
return NULL;
if (fseek(file, offset, SEEK_SET) < 0)
return NULL;
palptr = (struct RGB *)QMalloc(256L * (UInt32)sizeof(struct RGB));
if (ReadBytes(file, palptr, 768L) == FALSE)
{
QFree(palptr);
return NULL;
}
return palptr;
}
/*
* Save an RGB palette (256 * 3 bytes) to a file.
* Return the number of bytes written.
*/
UInt32 SavePalette256(FILE *file, struct RGB *palette256)
{
if (file == NULL || WriteBytes(file, palette256, 768L) == FALSE)
return 0L;
return 768L;
}
/* ------------------------------------------------------------------------- */
/* --- Routines for "flat" bitmaps ----------------------------------------- */
/*
* Create a new, empty bitmap.
*/
BitMap *NewBitMap()
{
BitMap *bmptr;
bmptr = (BitMap *)QMalloc((UInt32)sizeof(BitMap));
bmptr->width = 0;
bmptr->height = 0;
bmptr->data = NULL;
return bmptr;
}
/*
* Discard a bitmap and free memory.
*/
void FreeBitMap(BitMap *bmptr)
{
if (bmptr->data != NULL)
QFree(bmptr->data);
QFree(bmptr);
}
/*
* Read a bitmap from a file (width + height + data).
*/
BitMap *ReadBitMap(FILE *file, UInt32 offset)
{
BitMap *bmptr;
UInt32 w, h;
if (file == NULL)
return NULL;
bmptr = NewBitMap();
if ((fseek(file, offset, SEEK_SET) < 0)
|| (ReadInt32(file, &w) == FALSE)
|| (w > 65535L)
|| (w == 0L)
|| (ReadInt32(file, &h) == FALSE)
|| (h > 65535L)
|| (h == 0L))
{
FreeBitMap(bmptr);
return NULL;
}
bmptr->width = (UInt16)w;
bmptr->height = (UInt16)h;
bmptr->data = (UInt8 huge *)QMalloc(w * h);
if (ReadBytes(file, bmptr->data, w * h) == FALSE)
{
FreeBitMap(bmptr);
return NULL;
}
return bmptr;
}
/*
* Read raw bitmap data from a file. The width and height must be
* known in advance.
*/
BitMap *ReadRawBitMap(FILE *file, UInt32 offset, UInt16 width, UInt16 height)
{
BitMap *bmptr;
if (file == NULL)
return NULL;
bmptr = NewBitMap();
if (fseek(file, offset, SEEK_SET) < 0)
{
FreeBitMap(bmptr);
return NULL;
}
bmptr->width = width;
bmptr->height = height;
bmptr->data = (UInt8 huge *)QMalloc((UInt32)width * (UInt32)height);
if (ReadBytes(file, bmptr->data, (UInt32)width * (UInt32)height) == FALSE)
{
FreeBitMap(bmptr);
return NULL;
}
return bmptr;
}
/*
* Save a bitmap to a file (width + height + data).
* The number of bytes written is returned (0 if an error occured).
*/
UInt32 SaveBitMap(FILE *file, BitMap *bmptr)
{
UInt32 w, h;
if (file == NULL || bmptr->width == 0 || bmptr->height == 0)
return 0L;
w = (UInt32)(bmptr->width);
h = (UInt32)(bmptr->height);
if ((WriteInt32(file, &w) == FALSE)
|| (WriteInt32(file, &h) == FALSE)
|| (WriteBytes(file, bmptr->data, w * h) == FALSE))
return 0L;
return w * h + 8L;
}
/*
* Save raw bitmap data to a file.
* The number of bytes written is returned (0 if an error occured).
*/
UInt32 SaveRawBitMap(FILE *file, BitMap *bmptr)
{
if (file == NULL || bmptr->width == 0 || bmptr->height == 0)
return 0L;
if (WriteBytes(file, bmptr->data,
(UInt32)(bmptr->width) * (UInt32)(bmptr->height)) == FALSE)
return 0L;
return (UInt32)(bmptr->width) * (UInt32)(bmptr->height);
}
/*
* Print the contents of a bitmap in "outf".
*/
void DumpBitMap(FILE *outf, BitMap *bmptr)
{
UInt16 r, c;
UInt8 huge *x;
if (outf == NULL || bmptr == NULL)
return;
fprintf(outf, "Size = (%u * %u), %lu bytes.\n",
bmptr->width, bmptr->height,
(UInt32)(bmptr->width) * (UInt32)(bmptr->height));
x = bmptr->data;
for (r = 0; r < bmptr->height; r++)
{
for (c = 0; c < bmptr->width; c++)
fprintf(outf, "%02x ", *x++);
fprintf(outf, "\n");
}
}
/* ------------------------------------------------------------------------- */
/* --- Routines for PPM files (pbmplus) ------------------------------------ */
/*
* Save a bitmap as a PPM file (raw format, 24 bits per pixel). See
* the pbmplus package for more information. PPM files can be read by
* XV and other graphics programs and can be converted easily to other
* formats.
*/
UInt32 SavePPM(FILE *file, BitMap *bmptr, struct RGB *palette256)
{
char buf[20];
UInt32 size;
UInt16 r, c;
UInt8 huge *x;
if (file == NULL || bmptr->width == 0 || bmptr->height == 0
|| palette256 == NULL)
return 0L;
sprintf(buf, "P6\n%u %u\n255\n", bmptr->width, bmptr->height);
size = (UInt32)strlen(buf);
if (WriteBytes(file, buf, size) == FALSE)
return 0L;
x = bmptr->data;
for (r = 0; r < bmptr->height; r++)
for (c = 0; c < bmptr->width; c++)
{
if (WriteBytes(file, &(palette256[*x++]), 3) == FALSE)
return 0L;
size += 3L;
}
return size;
}
/* ------------------------------------------------------------------------- */
/* --- Routines for BMP files (MS Windows) --------------------------------- */
struct BMPHeader
{
/* BITMAPFILEHEADER */
UInt32 bfSize; /* total size of file */
UInt16 bfReserved1; /* always 0 */
UInt16 bfReserved2; /* always 0 */
Int32 bfOffBits; /* offset to start of bitmap data */
/* BITMAPINFOHEADER */
UInt32 biSize; /* size of bitmap header, always 40 here */
Int32 biWidth; /* width of the bitmap, in pixels */
Int32 biHeight; /* height of the bitmap, in pixels */
UInt16 biPlanes; /* number of planes, always 1 */
UInt16 biBitCount; /* number of bits per pixel, always 8 here */
UInt32 biCompression; /* compression, always 0 here */
UInt32 biSizeImage; /* size of the image */
Int32 biXPelsPerMeter; /* horizontal resolution */
Int32 biYPelsPerMeter; /* vertical resolution */
UInt32 biClrUsed; /* number of colors used, always 256 here */
UInt32 biClrImportant; /* number of "important" colors */
};
/*
* Save a bitmap as a BMP file (no compression, 8 bits per pixel). This can
* be read by most Windows programs. Note that this routine is simplified
* and will only work for bitmaps with a 256 colors palette.
*/
UInt32 SaveBMP(FILE *file, BitMap *bmptr, struct RGB *palette256)
{
struct BMPHeader bmphdr;
UInt8 huge *x;
UInt8 huge *buffer;
Int16 r, c;
UInt16 linesize;
UInt32 imgsize;
UInt32 imgoffset;
int i;
if (file == NULL || bmptr->width == 0 || bmptr->height == 0
|| palette256 == NULL)
return 0L;
linesize = (bmptr->width + 3) & (~3);
imgsize = (UInt32)linesize * (UInt32)bmptr->height;
imgoffset = 2L + (UInt32)sizeof(struct BMPHeader) + 1024L;
/* write the BMP header */
if (WriteBytes(file, "BM", 2L) == FALSE)
return 0L;
bmphdr.bfSize = SwapInt32(imgoffset + imgsize);
bmphdr.bfReserved1 = 0;
bmphdr.bfReserved2 = 0;
bmphdr.bfOffBits = SwapInt32(imgoffset);
bmphdr.biSize = SwapInt32(40L);
bmphdr.biWidth = SwapInt32((UInt32)bmptr->width);
bmphdr.biHeight = SwapInt32((UInt32)bmptr->height);
bmphdr.biPlanes = SwapInt16(1);
bmphdr.biBitCount = SwapInt16(8);
bmphdr.biCompression = 0L;
bmphdr.biSizeImage = SwapInt32(imgsize);
bmphdr.biXPelsPerMeter = SwapInt32(1181L); /* 30 dpi - low res */
bmphdr.biYPelsPerMeter = SwapInt32(1181L); /* 30 dpi - low res */
bmphdr.biClrUsed = SwapInt32(256L);
bmphdr.biClrImportant = 0L;
if (WriteBytes(file, &bmphdr, sizeof(struct BMPHeader)) == FALSE)
return 0L;
if (linesize < 1024)
buffer = (UInt8 huge *)QMalloc(1024L);
else
buffer = (UInt8 huge *)QMalloc((UInt32)linesize);
/* write the color palette */
x = buffer;
for (i = 0; i < 256; i++)
{
*x++ = palette256[i].B;
*x++ = palette256[i].G;
*x++ = palette256[i].R;
*x++ = 0;
}
if (WriteBytes(file, buffer, 1024L) == FALSE)
{
QFree(buffer);
return 0L;
}
/* write the bitmap data (from bottom to top) */
for (r = bmptr->height - 1; r >= 0; r--)
{
for (c = 0; c < bmptr->width; c++)
buffer[c] = bmptr->data[c + bmptr->width * r];
for(; c < linesize; c++)
buffer[c] = 0;
if (WriteBytes(file, buffer, (UInt32)linesize) == FALSE)
{
QFree(buffer);
return 0L;
}
}
QFree(buffer);
return imgoffset + imgsize;
}
/* end of file */